package faktorI;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.LinkedList;
import glavni.Simulacija;

public class FaktorISimulacija implements Simulacija {
	
	private LinkedList<FaktorIStanje> stanja; 
	private int korak;
	private String text;
	private int i = 0;
	private boolean izvrsenAlgoritam;
	
	public LinkedList<FaktorIStanje> getStanja(){return stanja;}
	public void korakNapred() {
		korak++;
		if (korak == 1) {
			FaktorIRadnaPovrs.instanca().dohvatiMenadzera().dozvoliNaPocetak();
			FaktorIRadnaPovrs.instanca().dohvatiTaster(3).setEnabled(true);
			FaktorIRadnaPovrs.instanca().dohvatiMenadzera().dozvoliKorakNazad();
			FaktorIRadnaPovrs.instanca().dohvatiTaster(4).setEnabled(true);
		}
		if (korak == stanja.size() - 1) {
			FaktorIRadnaPovrs.instanca().dohvatiMenadzera().zabraniKorakNapred();
			FaktorIRadnaPovrs.instanca().dohvatiTaster(5).setEnabled(false);
			FaktorIRadnaPovrs.instanca().dohvatiMenadzera().zabraniNaKraj();
			FaktorIRadnaPovrs.instanca().dohvatiTaster(6).setEnabled(false);
		}
		FaktorIRadnaPovrs.instanca().dohvatiPrikaz(3).requestFocus();
	}

	public void korakNazad() {
		korak--;
		if (korak == 0) {
			FaktorIRadnaPovrs.instanca().dohvatiMenadzera().zabraniNaPocetak();
			FaktorIRadnaPovrs.instanca().dohvatiTaster(3).setEnabled(false);
			FaktorIRadnaPovrs.instanca().dohvatiMenadzera().zabraniKorakNazad();
			FaktorIRadnaPovrs.instanca().dohvatiTaster(4).setEnabled(false);
		}
		if (korak == stanja.size() - 2) {
			FaktorIRadnaPovrs.instanca().dohvatiMenadzera().dozvoliKorakNapred();
			FaktorIRadnaPovrs.instanca().dohvatiTaster(5).setEnabled(true);
			FaktorIRadnaPovrs.instanca().dohvatiMenadzera().dozvoliNaKraj();
			FaktorIRadnaPovrs.instanca().dohvatiTaster(6).setEnabled(true);
		}
		FaktorIRadnaPovrs.instanca().dohvatiPrikaz(3).requestFocus();
	}

	public void naKraj() {
		while (korak < stanja.size() - 1)
			korakNapred();
		FaktorIRadnaPovrs.instanca().dohvatiPrikaz(3).requestFocus();
	}

	public void naPocetak() {
		KontrolerPetlji.isprazni();
		FaktorIRadnaPovrs.instanca().dohvatiTaster(0).setEnabled(false);
		FaktorIRadnaPovrs.instanca().dohvatiTaster(1).setEnabled(false);
		FaktorIRadnaPovrs.instanca().dohvatiTaster(2).setEnabled(false);
		FaktorIRadnaPovrs.instanca().dohvatiMenadzera().zabraniNaPocetak();
		FaktorIRadnaPovrs.instanca().dohvatiTaster(3).setEnabled(false);
		FaktorIRadnaPovrs.instanca().dohvatiMenadzera().zabraniKorakNazad();
		FaktorIRadnaPovrs.instanca().dohvatiTaster(4).setEnabled(false);
		FaktorIRadnaPovrs.instanca().dohvatiMenadzera().dozvoliKorakNapred();
		FaktorIRadnaPovrs.instanca().dohvatiTaster(5).setEnabled(true);
		FaktorIRadnaPovrs.instanca().dohvatiMenadzera().dozvoliNaKraj();
		FaktorIRadnaPovrs.instanca().dohvatiTaster(6).setEnabled(true);
		((FaktorIToolBar)FaktorIRadnaPovrs.instanca().dohvatiToolBar()).dozvoliIzvestaj();
		if(!izvrsenAlgoritam){
			LstPrav.instanca().dodeliBrojeve();
			LstZaklj.instanca().dodeliBrojeve();
			stanja = new LinkedList<FaktorIStanje>();
			korak = 0;
			algoritam();
		}
		else {
			while (korak > 0)
				korakNazad();
		}
	}
	
	
	public void algoritam(){
		i = 0;
		Zakljucak selektovanZaklj = LstZaklj.instanca().selZaklj();
		izracunajCFZ(selektovanZaklj);
		izvrsenAlgoritam = true;	
	}
	
	public Zakljucak izracunajCFZ(Zakljucak zaklj){
		try{
		if(zaklj.getBrojPkojaVodeDoZ()>1){
			text = "Korak "
				+ i++
				+ ":\n"
				+ "Do zaključka:"
				+ "\n" + zaklj.getNaziv() + " = z" + zaklj.getRedniBroj()
				+ "\nvode "+zaklj.getBrojPkojaVodeDoZ()+" pravila"
				+ "\nzbog toga moramo izračunati zbirne mere"
				+ "\npoverenja i nepoverenja zaključka:"
				+ "\n" + zaklj.getNaziv()
				+ "\npomoću formula:"
				+ "\n\nZbirna mera poverenja"
				+ "\nMBcum(z, e1,2)= 0 ako je MDcum(z, e1,2)= 1"
				+ "\nMBcum(z, e1,2)= \n   MB(z,e1) + MB(z,e2) - MB(z,e1) * MB(z,e2)"
				+ "\n\nZbirna mera nepoverenja"
				+ "\nMDcum(z, e1,2)= 0 ako je MBcum(z, e1,2)= 1"
				+ "\nMDcum(z, e1,2)= \n   MD(z,e1) + MD(z,e2) - MD(z,e1) * MD(z,e2)"
				+ "\n\na zatim i zbirni faktor izvesnosti"
				+ "\nna osnovu formule:"
				+ "\nCF(z, e1,2)= MBcum(z, e1,2) - MDcum(z, e1,2)"
				+ "\n\nGde su e1 i e2 dve nezavisne pretpostavke"
				;
			stanja.addLast(new FaktorIStanje(text));
		}
		int broj = 1;
		Pravilo pravilo = LstPrav.instanca().getPraviloSaZakljuckom(zaklj, broj);
		do{
			Zakljucak noviZakljucak = pravilo.getZakljucak();
			noviZakljucak.setRedniBroj(zaklj.getRedniBroj());
			
			if(!KontrolerPetlji.instanca().push(zaklj.getNaziv(), pravilo.getRedniBroj()))throw new Exception();
			ispisiPocetniText(noviZakljucak, pravilo);
			izracunajCFPP(noviZakljucak, pravilo);
			izracunajCFZkadaJePoznatCFPP(noviZakljucak, pravilo);
						
			if(broj != 1){
				izracunajZbirnuMBMD(zaklj, noviZakljucak);
			}
			broj++;
			pravilo = LstPrav.instanca().getPraviloSaZakljuckom(zaklj, broj);
		}while(pravilo != null);
		zaklj.setIzracunatFI(true);
		if(zaklj.getBrojPkojaVodeDoZ()>1){
			zaklj.setFaktorI(zaklj.getMB() - zaklj.getMD());
			text = "Korak "
				+ i++
				+ ":\n"
				+ "Sada, pošto smo izračunali zbirne mere "
				+ "\npoverenja i nepoverenja možemo izračunati"
				+ "\nzbirni faktor izvesnosti zaključka:"
				+ "\n" + zaklj.getNaziv() + " = z"+zaklj.getRedniBroj()
				+ "\npomoću formule:"
				+ "\nCF(z"+zaklj.getRedniBroj()+")= " 
				+ "MBcum(z"+zaklj.getRedniBroj()+","
				+ "e"+zaklj.getObradjenaPravila()+")-"
				+ "MDcum(z"+zaklj.getRedniBroj()+","
				+ "e"+zaklj.getObradjenaPravila()+")="
				+ "\n" + zaklj.getMB()+ " - " + zaklj.getMD()
				+ " = " + zaklj.getFaktorI()
				+ "\n\nOdnosno:"
				+ "\nCF("+zaklj+") = " + zaklj.getFaktorI()
				;
			stanja.addLast(new FaktorIStanje(text));
		}
		else{
			text = "Korak "
				+ i++
				+ ":\n"
				+ "Pošto nema više pravila koja vode do"
				+ "\nzaključka:\n" + zaklj.getNaziv() 
				+ "\nZaključujemo da je:"
				+ "\nCF("+zaklj.getNaziv()+")= "+zaklj.getFaktorI()
				;
			stanja.addLast(new FaktorIStanje(text));
		}	
		}catch(Exception e){
			FaktorIRadnaPovrs.instanca().dohvatiMenadzera().zabraniNaPocetak();
			FaktorIRadnaPovrs.instanca().dohvatiMenadzera().zabraniKorakNazad();
			FaktorIRadnaPovrs.instanca().dohvatiMenadzera().zabraniKorakNapred();
			FaktorIRadnaPovrs.instanca().dohvatiMenadzera().zabraniNaKraj();
			FaktorIRadnaPovrs.instanca().novaSimulacija();
			new GreskaD(FaktorIRadnaPovrs.instanca(), "Greška! Pogrešno ste uneli pravila!" +
					"\nNapomena:" +
					"\nPreduslov pravila ne sme direktno niti indirektno" +
					"\nzavisiti od zaključka tog pravila.");
		}
		return zaklj;
	}
	
	public void izracunajCFPP(Zakljucak zaklj, Pravilo pravilo){
		text = "Korak "
			+ i++
			+ ":\n"
			
			+ "Meru poverenja:"
			+ "\nMB(z"+zaklj.getRedniBroj()+",eP"+ pravilo.getRedniBroj() + ")" 
			+ "\ni mera nepoverenja:"
			+ "\nMD(z"+zaklj.getRedniBroj()+",eP"+ pravilo.getRedniBroj() + ")"
			+ "\nzaključka z"+zaklj.getRedniBroj() + " na osnovu pravila P" +pravilo.getRedniBroj()
			+ "\nračunaju se pomoću formule:"
			
			+ "\nMB(z"+zaklj.getRedniBroj()+",eP"+ pravilo.getRedniBroj()+")" 
			+ " = MB'(z"+zaklj.getRedniBroj()+",eP"+ pravilo.getRedniBroj()+")" 
			+ "* max(0,CF(eP"+ pravilo.getRedniBroj()+"))"
			+ "\nMD(z"+zaklj.getRedniBroj()+",eP"+ pravilo.getRedniBroj()+")"
			+ " = MD'(z"+zaklj.getRedniBroj()+",eP"+ pravilo.getRedniBroj()+")"
			+ "* max(0,CF(eP"+ pravilo.getRedniBroj()+"))"
			
			+ "\n\nGde su:"
			+ "\nMB'( z"+zaklj.getRedniBroj()+" , eP"+ pravilo.getRedniBroj() 
			+ ")-mera poverenja zaključka"
			+ "\n z"+zaklj.getRedniBroj()
			+ " na osnovu pravila P" +pravilo.getRedniBroj()
			+ "\nMD'( z"+zaklj.getRedniBroj()+" , eP"+ pravilo.getRedniBroj()
			+ ")-mera nepoverenja zaključka"
			+ "\n z"+zaklj.getRedniBroj()
			+ " na osnovu pravila P" + pravilo.getRedniBroj()
		    + "\nu slučaju potpune izvesnosti pretpostavke"
		    + "\npravila P" + pravilo.getRedniBroj()
		    
			+ "\n\nCF(eP"+ pravilo.getRedniBroj() 
			+")-faktor izvesnosi pretpostavke "
			+ "\npravila P"+pravilo.getRedniBroj()
		    +"\n\n"
		    ;
		stanja.addLast(new FaktorIStanje(text));
		
		text = "Korak "
			+ i++
			+ ":\n"
			+ "Pošto su:"
			+ "\nMB'( z"+zaklj.getRedniBroj()+" , eP"+ pravilo.getRedniBroj() + ")"
			+ "\ni"
			+ "\nMD'( z"+zaklj.getRedniBroj()+" , eP"+ pravilo.getRedniBroj() + ")"
		    + "\nzadate u postavci pravila,"
		    + "\nostaje nam da izračunamo:"
		    + "\nCF(eP"+ pravilo.getRedniBroj() + ")."
		    
			+ "\n\nFaktor izvesnosi pretpostavke "
		    + "\nse računa pomoću formle:"
			+ "\nCF(eP"+pravilo.getRedniBroj()+")"
			+ "= MB(eP" + pravilo.getRedniBroj()+")"
			+ " - MD(eP"+pravilo.getRedniBroj()+")"
			
			+ "\n\ngde su:"
			+ "\nMB(eP" + pravilo.getRedniBroj()+")"
			+ "\n -mera poverenja pretpostavke pravila P" + pravilo.getRedniBroj()
			+ "\nMD(eP" + pravilo.getRedniBroj()+")"
			+ "\n -mera nepoverenja pretpostavke pravila P" + pravilo.getRedniBroj()
			;
		stanja.addLast(new FaktorIStanje(text));

		izracunajMBMDElemPred(pravilo);
		
		text = "Korak "
			+ i++
			+ ":\n"
			+ "Pošto smo odrediti meru poverenja i meru" 
			+ "\nnepoverenja svih elemenata pretpostavke "
			+ "\npravila P"+pravilo.getRedniBroj()+ " posebno,"
			+ "\nmožemo izračunati ukupnu meru poverenja:"
			+ "\nMB(eP"+ pravilo.getRedniBroj() +")"
			+ "\ni meru nepoverenja:"
			+ "\nMD(eP"+ pravilo.getRedniBroj() +")"
			+ "\npretpostavke pravila P"+pravilo.getRedniBroj() + "."
			;
		stanja.addLast(new FaktorIStanje(text));
		
		
		text = "Korak "
			+ i++
			+ ":\n";
		text += Calculator.calculate(pravilo);
		stanja.addLast(new FaktorIStanje(text));
		
		text = "Korak "
			+ i++
			+ ":\n";
		
		text += "Pošto smo izračunali meru poverenja i "
			+ "\nmeru nepoverenja, računamo faktor "
			+ "\nizvesnosti pretpostavke pravila P" + pravilo.getRedniBroj() + ":"
			+ "\nCF(eP"+pravilo.getRedniBroj()+")"
			+ "= MB(eP" + pravilo.getRedniBroj()+")"
			+ " - MD(eP"+pravilo.getRedniBroj()+")"
			
			+ "\n\nCF(eP"+pravilo.getRedniBroj()+")"
			+ " = " + pravilo.getPreduslov().getMB()
			+ " - " + pravilo.getPreduslov().getMD()
			+ " = " + pravilo.getPreduslov().getFaktorI();
			;
		stanja.addLast(new FaktorIStanje(text));
	}
	
	public void izracunajMBMDElemPred(Pravilo pravilo){
		Iterator iterator = new Iterator(pravilo.getPreduslov().getElemList()); 
		PredElem element = (PredElem)iterator.first();
		text = "Korak "
			+ i++
			+ ":\n";
		
		text +="Da bismo izračunali"
			+ "\nMB(eP" + pravilo.getRedniBroj()+")"
			+ "\ni"
			+ "\nMD(eP" + pravilo.getRedniBroj()+")"
			+ "\nmoramo odrediti meru poverenja i meru" 
			+ "\nnepoverenja svih elemenata pretpostavke."
			+ "\n"
			;
		stanja.addLast(new FaktorIStanje(text));
		do{
			if(element.jeOperand()){
				if(!element.jeZakljucak()){
					text = "Korak "
						+ i++
						+ ":\n";
					text +="Elemenat:" +
							"\n" + element + 
							"\npretpostavke pravila P"+pravilo.getRedniBroj()+" je opažanje" +
							"\nčiji je faktor izvesnosti zadat u postavci" +
							"\ni ne moramo ga računati.";
					
					if(element.getFaktorI() > 0){
						text += "\nPošto je zadati faktor izvesnosti elementa:" 
							+ "\n" + element
							+ "\nCF("+ element +") = "+ element.getFaktorI()
							+ "\nveci od nule:"
							+ "\nmera poverenja u njega je:"
							+ "\nMB("+ element +") = \nCF("+ element +") = " + element.getMB()
							+ "\na mera nepoverenja u njega je:"
							+ "\nMD("+ element +") = " + element.getMD()
							+ "\n"
							;
					}
					else{//faktorI < 0
						text += "\nPošto je zadati faktor izvesnosti elementa:" 
							+ "\n"+ element
							+ "\nCF("+ element +") = "+ element.getFaktorI()
							+ "\nmanji od nule:"
							+ "\nmera poverenja u njega je:"
							+ "\nMB("+ element +")= " +element.getMB()
							+ "\na mera nepoverenja u njega je:"
							+ "\nMD("+ element +") = \n|CF("+ element +")| = " +element.getMD()
							+ "\n"
							;
					}
					stanja.addLast(new FaktorIStanje(text));
				}
				else{//je zakljucak
					text = "Korak "
						+ i++
						+ ":\n";
					text+="Elemenat:" +
						"\n" + element + 
						"\npretpostavke pravila P"+pravilo.getRedniBroj();
					if(element.negacija)
						text += "\nje negacija zaključaka nekog drugog";
					else
						text += "\nje zaključak nekog drugog";
					Zakljucak zakljucak =LstZaklj.instanca().dohvatiZakljSaImenom(element.getNaziv());
					if(!zakljucak.getIzracunatFI()){
						text +=	"\npravila pa njegov faktor izvesnosti " +
								"\nmoramo da izračunamo.";
						stanja.addLast(new FaktorIStanje(text));
						zakljucak = LstZaklj.instanca().dohvatiZakljSaImenom(element.getNaziv());
						izracunajCFZ(zakljucak);
						element.setMB(zakljucak.getMB());
						element.setMD(zakljucak.getMD());
					}
					else{//izracunato
						element.setMB(zakljucak.getMB());
						element.setMD(zakljucak.getMD());
						text +=	"\npravila šiju smo meru izvesnosti \n" +
							"i meru neizvesnosti već izračunali:\n" +
							"MB("+zakljucak+") = " + zakljucak.getMB()+"\n" +
							"MD("+zakljucak+") = " + zakljucak.getMD()
						;
						stanja.addLast(new FaktorIStanje(text));	
					}
					if(element.negacija){
						text = "Korak "
							+ i++
							+ ":\n";
						text += "Pošto je elemenat \n" +
							"" + element +
							"\nnegacija zaključka čiji smo faktor\n" +
							"izvesnosti izračunali onda važi:\n" +
							"MB("+element+") = MD("+zakljucak+") = "+element.getMB()+"\n" +
							"MD("+element+") = MB("+zakljucak+") = "+element.getMD() 
						;
						stanja.addLast(new FaktorIStanje(text));
					}
				}//zakljucak
			}
			element = (PredElem)iterator.next();
		}while(!iterator.isDone());
	}
	
	public Zakljucak izracunajZbirnuMBMD(Zakljucak zaklj, Zakljucak noviZaklj){
		double MB = zaklj.getMB();
		double MD = zaklj.getMD();
		zaklj.setMB((MB + noviZaklj.getMB()) - MB * noviZaklj.getMB());
		zaklj.setMD((MD + noviZaklj.getMD()) - MD * noviZaklj.getMD());
		
		text = "Korak "
			+ i++
			+ ":\n"
			+ "Pošto smo izračunali meru poverenja i "
			+ "\nmeru nepoverenja zaključka:"
			+ "\n" + noviZaklj.getNaziv()
			+ "\nna osnovu pravila " + noviZaklj.getObradjenaPravila() 
			+ " uračunamo ih u zbirnu"
			+ "\nmeru poverenja i nepoverenja pomoću formula:"
			
			+ "\n\nZbirna mera poverenja"
			+ "\nMBcum(z" + zaklj.getRedniBroj()
			+ ", e" + zaklj.getObradjenaPravila() +  noviZaklj.getObradjenaPravila()
			+ ")= \nMB(z" + zaklj.getRedniBroj()
			+ ",e" + zaklj.getObradjenaPravila()
			+ ")+MB(z,e" + noviZaklj.getObradjenaPravila()
			+ ") - MB(z,e" + zaklj.getObradjenaPravila()
			+ ")*MB(z,e" + noviZaklj.getObradjenaPravila()
			+ ")="
			+ "\n " + MB + " + " + noviZaklj.getMB()
			+ " - "+ MB +" * " + noviZaklj.getMB()
			+ " = " + zaklj.getMB()
			
			+ "\n\nZbirna mera nepoverenja"
			+ "\nMDcum(z" + zaklj.getRedniBroj()
			+ ", e" + zaklj.getObradjenaPravila() + noviZaklj.getObradjenaPravila()
			+ ")= \nMD(z" + zaklj.getRedniBroj()
			+ ",e" + zaklj.getObradjenaPravila()
			+ ")+MD(z,e" + noviZaklj.getObradjenaPravila()
			+ ") - MD(z,e" + zaklj.getObradjenaPravila()
			+ ")*MD(z,e" + noviZaklj.getObradjenaPravila()
			+ ")="
			+ "\n " + MD + " + " + noviZaklj.getMD()
			
			+ " - "+ MD +" * " + noviZaklj.getMD()
			+ " = " + zaklj.getMD()
			;
		zaklj.dodajObradjenoPravilo(noviZaklj.getObradjenaPravila());
		stanja.addLast(new FaktorIStanje(text));
		return zaklj;
	}
	
	public void ispisiPocetniText(Zakljucak zaklj, Pravilo pravilo){
		text = "Korak "
			+ i++
			+ ":\n"
			+ "Računamo faktor izvesnosti zaključka:\n"
			+ "" + zaklj.getNaziv() + " = z" + zaklj.getRedniBroj()
			+ "\nna osnovu pravila P"+pravilo.getRedniBroj()+":"
			+ "\n" + pravilo
			+ "\npomoću formule:"
			+ "\nCF(z"+zaklj.getRedniBroj()+",eP"+pravilo.getRedniBroj()
			+") = MB( z"+zaklj.getRedniBroj()+",eP" + pravilo.getRedniBroj()+ ")"
			+" - MD(z"+zaklj.getRedniBroj()+",eP"+pravilo.getRedniBroj()+")"
			+ "\n\nGde su:"
			+ "\nMB(z"+zaklj.getRedniBroj()+",eP"+ pravilo.getRedniBroj() 
			+")- mera poverenja zaključka z"+zaklj.getRedniBroj()
			+ "\n               na osnovu pravila P" +pravilo.getRedniBroj()
			+ "\nMD(z"+zaklj.getRedniBroj()+",eP"+ pravilo.getRedniBroj()
			+")- mera nepoverenja zaključka z"+zaklj.getRedniBroj()
			+ "\n               na osnovu pravila P" + pravilo.getRedniBroj() + ".";
		stanja.addLast(new FaktorIStanje(text));
	}
	
	public void izracunajCFZkadaJePoznatCFPP(Zakljucak zaklj, Pravilo pravilo){
		zaklj.setMB(pravilo.getMBZ()* Calculator.max(0,pravilo.getPreduslov().getFaktorI()));
		zaklj.setMD(pravilo.getMDZ()* Calculator.max(0,pravilo.getPreduslov().getFaktorI()));
		text ="Korak "
			+ i++
			+ ":\n"
			+ "Mera poverenja i nepoverenja zaključka:"
			+ "\n" + zaklj.getNaziv()
			+ "\nna osnovu pravila P" + pravilo.getRedniBroj()
			+ "\nse sada mogu izračunati na osnovu formula:"
			+ "\nMB(z"+zaklj.getRedniBroj()+",eP"+ pravilo.getRedniBroj()+")" 
			+ " = MB'(z"+zaklj.getRedniBroj()+",eP"+ pravilo.getRedniBroj()+")" 
			+ "* max(0,CF(eP"+ pravilo.getRedniBroj()+"))"
			+ "\nMD(z"+zaklj.getRedniBroj()+",eP"+ pravilo.getRedniBroj()+")"
			+ " = MD'(z"+zaklj.getRedniBroj()+",eP"+ pravilo.getRedniBroj()+")"
			+ "* max(0,CF(eP"+ pravilo.getRedniBroj()+"))"
			
			+ "\nMB(z"+zaklj.getRedniBroj()+",eP"+ pravilo.getRedniBroj()+")"
			+ " = "+ pravilo.getMBZ()+ " * max(0,"+ pravilo.getPreduslov().getFaktorI()+"))"
			+ " = " + zaklj.getMB() 
			+ "\nMD(z"+zaklj.getRedniBroj()+",eP"+ pravilo.getRedniBroj()+")"
			+ " = "+ pravilo.getMDZ()+ " * max(0,"+ pravilo.getPreduslov().getFaktorI()+"))"
			+ " = " + zaklj.getMD()
			
			+ "\n\nGde su:"
			+ "\nMB'( z"+zaklj.getRedniBroj()+" , eP"+ pravilo.getRedniBroj() 
			+ ")-mera poverenja zaključka"
			+ "\n z"+zaklj.getRedniBroj()
			+ " na osnovu pravila P" +pravilo.getRedniBroj()
			+ "\nMD'( z"+zaklj.getRedniBroj()+" , eP"+ pravilo.getRedniBroj()
			+ ")-mera nepoverenja zaključka"
			+ "\n z"+zaklj.getRedniBroj()
			+ " na osnovu pravila P" + pravilo.getRedniBroj()
		    + "\nu slučaju potpune izvesnosti pretpostavke"
		    + "\npravila P" + pravilo.getRedniBroj()
		    ;
		stanja.addLast(new FaktorIStanje(text));
		
		zaklj.setFaktorI(zaklj.getMB()-zaklj.getMD());
		zaklj.dodajObradjenoPravilo("P"+pravilo.getRedniBroj());
		
		text ="Korak "
			+ i++
			+ ":\n"
			+ "Sada na osnovu početne formule računamo"
			+ "\nfaktor izvesnosti zaključka:\n"
			+ "" + zaklj + " = z" + zaklj.getRedniBroj()
			+ "\nna osnovu pravila P"+pravilo.getRedniBroj()+":"
			+ "\n" + pravilo
			+ "\n\nCF(z"+zaklj.getRedniBroj()+",eP" + pravilo.getRedniBroj()
			+ ") = MB(z"+zaklj.getRedniBroj()+",eP" + pravilo.getRedniBroj()+")"
			+ " - MD(z"+zaklj.getRedniBroj()+",eP"+pravilo.getRedniBroj()+")"
			+ "\nCF(z"+zaklj.getRedniBroj()+",eP" + pravilo.getRedniBroj()+")"
		    + " = "+ zaklj.getMB() +" - " +zaklj.getMD()
		    + " = " + Double.toString(zaklj.getFaktorI());
			;
			stanja.addLast(new FaktorIStanje(text));
	}
	
	public void refresh() {
		if (stanja != null && !stanja.isEmpty()) {
			FaktorIStanje stanje = stanja.get(korak);
			FaktorIRadnaPovrs.instanca().dohvatiPrikaz(3).setText(stanje.dohvatiObjasnjenja());
		} else {
			FaktorIRadnaPovrs.instanca().dohvatiPrikaz(3).setText(null);
		}
	}
	
	
	
	public void snimi(String fajl) {
		ObjectOutputStream oos = null;
		try {
			oos = new ObjectOutputStream(new FileOutputStream(fajl));
			oos.writeObject(LstPrav.instanca());
			oos.writeObject(LstZaklj.instanca());
			oos.writeObject(LstOpaz.instanca());
			oos.writeObject(KontrolerPetlji.instanca());
			oos.writeObject(stanja);
			oos.writeInt(korak);
			oos.writeBoolean(izvrsenAlgoritam);
			oos.flush();
		} catch (FileNotFoundException e) {
			new GreskaD(FaktorIRadnaPovrs.instanca(), "Greška: nema fajla " + fajl);
		} catch (IOException e) {
			new GreskaD(FaktorIRadnaPovrs.instanca(), "Greška pri upisu podataka u fajl: " + fajl);
		} finally {
			try {
				if (oos != null)
					oos.close();
			} catch (IOException e) {
				new GreskaD(FaktorIRadnaPovrs.instanca(), "Greška pri zatvaranju fajla: " + fajl);
			}
		}
	}
	
	
	public void ucitaj(String fajl) {
		ObjectInputStream ois = null;
		try {
			ois = new ObjectInputStream(new FileInputStream(fajl));
			LstPrav.setPravila((LstPrav) ois.readObject());
			LstZaklj.setZakljucke((LstZaklj) ois.readObject());
			LstOpaz.setOpazanja((LstOpaz) ois.readObject());
			KontrolerPetlji.instanca().postaviInstancu((KontrolerPetlji) ois.readObject());
			stanja = (LinkedList<FaktorIStanje>) ois.readObject();
			FaktorIRadnaPovrs.instanca().dohvatiPrikaz(0).setText(
					LstPrav.instanca().toString());
			FaktorIRadnaPovrs.instanca().dohvatiPrikaz(1).setText(
					LstOpaz.instanca().toString());
			if(LstZaklj.instanca().selZaklj() != null)
			FaktorIRadnaPovrs.instanca().dohvatiPrikaz(2).setText("ZAKLJUČAK:\n" +LstZaklj.instanca().selZaklj().toString());
			korak = ois.readInt();
			izvrsenAlgoritam = ois.readBoolean();
			FaktorIRadnaPovrs.instanca().dohvatiMenadzera().zabraniNaPocetak();
			FaktorIRadnaPovrs.instanca().dohvatiMenadzera().zabraniKorakNapred();
			FaktorIRadnaPovrs.instanca().dohvatiMenadzera().zabraniKorakNazad();
			FaktorIRadnaPovrs.instanca().dohvatiMenadzera().zabraniNaKraj();
			FaktorIRadnaPovrs.instanca().dohvatiTaster(0).setEnabled(true);
			FaktorIRadnaPovrs.instanca().dohvatiTaster(1).setEnabled(true);
			FaktorIRadnaPovrs.instanca().dohvatiTaster(2).setEnabled(true);
			if (FaktorIRadnaPovrs.instanca().startnoStanjeKompletno())
				FaktorIRadnaPovrs.instanca().dohvatiMenadzera().dozvoliNaPocetak();
			if (stanja != null) {
				((FaktorIToolBar)FaktorIRadnaPovrs.instanca().dohvatiToolBar()).dozvoliIzvestaj();
				if (korak == 0)
					FaktorIRadnaPovrs.instanca().dohvatiMenadzera().zabraniNaPocetak();
					FaktorIRadnaPovrs.instanca().dohvatiTaster(3).setEnabled(false);					FaktorIRadnaPovrs.instanca().dohvatiTaster(3).setEnabled(true);
				if (korak > 0)
					FaktorIRadnaPovrs.instanca().dohvatiMenadzera().dozvoliKorakNazad();
					FaktorIRadnaPovrs.instanca().dohvatiTaster(4).setEnabled(true);
				if (korak < stanja.size() - 1) {
					FaktorIRadnaPovrs.instanca().dohvatiMenadzera().dozvoliKorakNapred();
					FaktorIRadnaPovrs.instanca().dohvatiTaster(5).setEnabled(true);
					FaktorIRadnaPovrs.instanca().dohvatiMenadzera().dozvoliNaKraj();
					FaktorIRadnaPovrs.instanca().dohvatiTaster(6).setEnabled(true);
				}
				FaktorIRadnaPovrs.instanca().dohvatiTaster(0).setEnabled(false);
				FaktorIRadnaPovrs.instanca().dohvatiTaster(1).setEnabled(false);
				FaktorIRadnaPovrs.instanca().dohvatiTaster(2).setEnabled(false);
			}
		} catch (FileNotFoundException e) {
			new GreskaD(FaktorIRadnaPovrs.instanca(), "Greška: nema fajla " + fajl);
		} catch (IOException e) {
			new GreskaD(FaktorIRadnaPovrs.instanca(), "Greška pri čitanju podataka iz fajla: " + fajl);
		} catch (ClassNotFoundException e) {
			new GreskaD(FaktorIRadnaPovrs.instanca(), "Greška pri učitavanju simulacije!");
		} finally {
			try {
				if (ois != null)
					ois.close();
			} catch (IOException e) {
				new GreskaD(FaktorIRadnaPovrs.instanca(), "Greška pri zatvaranju fajla: " + fajl);
			}
		}
	}
}
